package org.pine.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Getter;
import org.pine.api.beans.request.PageRequest;
import org.pine.manager.query.BaseQuery;
import org.pine.model.entity.BaseExtendFields;
import org.pine.model.mapper.BaseMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * 基础管理器
 *
 * @author pine
 * @version v1.0
 * @since 2025-04-12 14:31
 */
@Getter
public abstract class BaseManager
        <Mapper extends BaseMapper<Entity>,
        Entity extends BaseExtendFields<Long>,
        EntityBo extends Entity,
        Query extends BaseQuery,
        EntityConvertor extends org.pine.common.convertor.EntityConvertor<Entity, EntityBo>> extends ServiceImpl<Mapper, Entity> {

    @Autowired
    protected Mapper mapper;
    @Autowired
    protected EntityConvertor entityConvertor;

    /**
     * 批量保存默认大小
     */
    protected static final int DEFAULT_BATCH_SIZE = 100;
    protected static final String ASC = "asc";
    protected static final String DESC = "desc";

    protected static final String DEFAULT_ORDER_BY_FIELD = "id";

    /**
     * 批量保存
     *
     * @param entityList 实体列
     */
    public boolean saveBatch(Collection<Entity> entityList) {
        if (!ObjectUtils.isEmpty(entityList)) {
            this.mapper.insertBatchSomeColumn(new ArrayList<>(entityList), DEFAULT_BATCH_SIZE);
            return true;
        }
        return false;
    }

    /**
     * 批量保存
     *
     * @param entityList 实体列表
     * @param batchSize  批量大小
     */
    public boolean saveBatch(Collection<Entity> entityList, int batchSize) {
        if (!ObjectUtils.isEmpty(entityList)) {
            this.mapper.insertBatchSomeColumn(new ArrayList<>(entityList), Math.max(batchSize, DEFAULT_BATCH_SIZE));
            return true;
        }
        return false;
    }

    /**
     * 根据查询条件查询单条数据
     *
     * @param query 查询条件
     * @return 业务对象
     */
    public EntityBo getOneBo(Query query) {
        LambdaQueryWrapper<Entity> queryWrapper = this.encapsulateQueryWrapper(query);
        queryWrapper.last(" limit 1");
        Entity entity = this.mapper.selectOne(queryWrapper);
        return entityConvertor.entityToEntityBo(entity);
    }

    /**
     * 封装查询条件
     *
     * @param query 请求参数
     * @return 查询条件wrapper
     */
    protected LambdaQueryWrapper<Entity> encapsulateQueryWrapper(Query query) {
        QueryWrapper<Entity> wrapper = new QueryWrapper<>();
        if (Objects.isNull(query)) {
            return wrapper.lambda();
        }

        // 处理查询字段
        String[] underLineFields = query.convertToUnderLineFields();
        if (Objects.nonNull(underLineFields) && underLineFields.length > 0) {
            wrapper.select(underLineFields);
        }

        // 处理排序规则
        String orderBy = query.getOrderBy();
        if (StrUtil.isNotBlank(orderBy)) {
            String[] orderByExpressions = orderBy.split(StrUtil.COMMA);
            List<String> ascFields = new ArrayList<>();
            List<String> descFields = new ArrayList<>();
            for (String orderByExpression : orderByExpressions) {
                if (orderByExpression.endsWith(ASC)) {
                    ascFields.add(orderByExpression.replace(StrUtil.DASHED + ASC, StrUtil.EMPTY));
                    continue;
                }
                if (orderByExpression.endsWith(DESC)) {
                    descFields.add(orderByExpression.replace(StrUtil.DASHED + DESC, StrUtil.EMPTY));
                }
            }

            // 没有排序规则，使用ID倒序排序
            if (CollUtil.isEmpty(descFields) && CollUtil.isEmpty(ascFields)) {
                wrapper.orderByDesc(DEFAULT_ORDER_BY_FIELD);
            } else {
                if (CollUtil.isNotEmpty(ascFields)) {
                    wrapper.orderByAsc(ascFields);
                }
                if (CollUtil.isNotEmpty(descFields)) {
                    wrapper.orderByDesc(descFields);
                }
            }
        } else {
            // 没有排序规则，使用ID倒序排序
            wrapper.orderByDesc(DEFAULT_ORDER_BY_FIELD);
        }

        LambdaQueryWrapper<Entity> lambda = wrapper.lambda();
        lambda.eq(Objects.nonNull(query.getId()), Entity::getId, query.getId());
        lambda.in(CollUtil.isNotEmpty(query.getIdList()), Entity::getId, query.getIdList());
        lambda.ge(Objects.nonNull(query.getCreateTimeStart()), Entity::getCreateTime, query.getCreateTimeStart());
        lambda.le(Objects.nonNull(query.getCreateTimeEnd()), Entity::getCreateTime, query.getCreateTimeEnd());
        return lambda;
    }

    /**
     * 分页查询实现
     *
     * @param request 请求参数
     * @return 响应结果
     */
    public IPage<EntityBo> listPageBos(PageRequest<Query> request) {
        // 组装查询条件
        LambdaQueryWrapper<Entity> queryWrapper = encapsulateQueryWrapper(request.getData());

        // 分页查数据
        Page<Entity> objectPage = new Page<>(request.getPageNum(), request.getPageSize());
        objectPage.setSearchCount(true);
        Page<Entity> entityPage = this.mapper.selectPage(objectPage, queryWrapper);

        // 根据查询结果组装业务对象列表
        List<EntityBo> entityBos = entityConvertor.entityToEntityBo(entityPage.getRecords());

        // 返回业务分页结果
        return Page.<EntityBo>of(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal(), entityPage.searchCount()).setRecords(entityBos);
    }

    /**
     * 查询列表
     *
     * @param queryWrapper 查询条件
     * @return 实体Bo列表
     */
    public List<EntityBo> listBos(Wrapper<Entity> queryWrapper) {
        List<Entity> entities = this.mapper.selectList(queryWrapper);
        return entityConvertor.entityToEntityBo(entities);
    }

    /**
     * 通过主键列表查询实体列表
     *
     * @param ids 主键列表
     * @return 实体Bo列表
     */
    public List<EntityBo> listBosByIds(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<Entity> entities = this.mapper.selectBatchIds(ids);
        return entityConvertor.entityToEntityBo(entities);
    }

    /**
     * 查询列表
     *
     * @param query 查询条件
     * @return 实体Bo列表
     */
    public List<EntityBo> listBos(Query query) {
        List<Entity> entities = this.mapper.selectList(encapsulateQueryWrapper(query));
        return entityConvertor.entityToEntityBo(entities);
    }
}
